package com.geovis.emergency.spd.biz.pc.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.geovis.common.auth.util.AuthUtil;
import com.geovis.emergency.spd.biz.pc.mapper.PcCheckInMapper;
import com.geovis.emergency.spd.biz.pc.service.IPcCheckInService;
import com.geovis.emergency.spd.biz.pc.service.IPcDrillService;
import com.geovis.emergency.spd.biz.pc.service.IPcMessageService;
import com.geovis.emergency.spd.entity.pc.entity.PcCheckIn;
import com.geovis.emergency.spd.entity.pc.entity.PcDrill;
import com.geovis.emergency.spd.entity.pc.entity.PcMessage;
import com.geovis.emergency.spd.entity.pc.pojo.constant.PcMessageConstant;
import com.geovis.emergency.spd.entity.pc.pojo.dto.PcCheckInSaveDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Date;

/**
 * <p>
 * 应急预案模块-签到表 服务实现类
 * </p>
 *
 * @author 曾德实
 * @since 2022-04-30
 */

@Service
@RequiredArgsConstructor
@Slf4j
public class PcCheckInServiceImpl extends ServiceImpl<PcCheckInMapper, PcCheckIn> implements IPcCheckInService {

    private final RedissonClient redissonClient;

    private final IPcDrillService pcDrillService;

    private final IPcMessageService pcMessageService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void signIn(PcCheckInSaveDTO dto) {
        RLock lock = null;
        try {
            PcDrill drill = pcDrillService.getById(dto.getPcDrillId());
            Assert.isFalse(ObjectUtil.isEmpty(drill), "演练不存在");
            lock = redissonClient.getLock("sign_in_" + drill.getId() + AuthUtil.getCurrentUserId());
            if (lock.tryLock()) {
                long count = count(Wrappers.lambdaQuery(PcCheckIn.class)
                        .eq(PcCheckIn::getPersonId, AuthUtil.getCurrentUserId())
                        .eq(PcCheckIn::getPcDrillId, drill.getId())
                );
                Assert.isFalse(count > 0, "您已签到成功");
                PcCheckIn checkIn = BeanUtil.copyProperties(dto, PcCheckIn.class);
                checkIn.setCheckInTime(LocalDateTime.now())
                        .setPersonId(AuthUtil.getCurrentUserId())
                        .setPersonName(AuthUtil.getCurrentUsername());
                save(checkIn);
                // 发送消息
                PcMessage message = new PcMessage();
                message.setPcDrillId(checkIn.getPcDrillId())
                        .setContent(StrUtil.format("演练值班组【已签到】"))
                        .setRelatedId(checkIn.getPcDrillId())
                        .setTitle("值班签到")
                        .setType(PcMessageConstant.TYPE_DRILL_SIGN);
                pcMessageService.save(message);
                // 发送socket消息提示
                pcMessageService.sendSocketMessage(message);
            }
        } finally {
            if (null != lock && lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }

    @Override
    public PcCheckIn getUserDaySignInfo(String currentUserId, Date date) {
        return baseMapper.getUserDaySignInfo(currentUserId, DateUtil.beginOfDay(date),DateUtil.endOfDay(date));
    }

}
